package com.jwm.client.soft;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import oshi.util.Util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 崔洁
 */
@Component
public class ExecuteCommand {
    private static final Logger logger = LoggerFactory.getLogger(ExecuteCommand.class);

    private static final Map<String, String> STATES = new HashMap<String, String>() {{
        put("RUNNING", "运行中");
        put("STOPPED", "停止中");
        put("START_PENDING", "启动中");
    }};

    public static void main(String[] args) {
        ExecuteCommand executeCommand = new ExecuteCommand();

        // System.out.println(executeCommand.exeBatQuery("nginx"));
        // System.out.println(executeCommand.exeServiceQuery("activeMq"));

        // System.out.println(executeCommand.exeTomcatStop("D:/server/apache-tomcat-7.0.108-1"));
        // System.out.println(executeCommand.exeTomcatStart("D:/server/apache-tomcat-7.0.108"));
        // System.out.println(executeCommand.exeServiceStop("activeMq"));
        // System.out.println(executeCommand.exeServiceStart("activeMq"));
        // System.out.println(executeCommand.exeNginxReload("D:/server/nginx-1.14.0"));
        System.out.println(executeCommand.exeBatRestart("D:/home", "30002.bat"));
    }

    public String exeTomcatStop(String path) {
        logger.warn("客户端 -> exeTomcatStop - 开始:{}:{}", path);
        String exe = exeCommand("cmd", "/c", "cd", "/d", path + "/bin", "&&", "shutdown.bat");
        logger.warn("客户端 -> exeTomcatStop - 结束:{}", exe);
        return exe;
    }

    public String exeTomcatStart(String path) {
        logger.warn("客户端 -> exeTomcatStart - 开始:{}", path);
        String exe = exeCommand("cmd", "/c", "cd", "/d", path + "/bin", "&&", "startup.bat");
        logger.warn("客户端 -> exeTomcatStart - 结束:{}", exe);
        return exe;
    }

    public String exeNginxReload(String path) {
        logger.warn("客户端 -> exeNginxReload - 开始:{}", path);
        String exe = exeCommand("cmd", "/c", "cd", "/d", path, "&&", "nginx", "-s", "reload");
        logger.warn("客户端 -> exeNginxReload - 结束:{}", exe);
        return exe;
    }

    public String exeBatRestart(String path, String bat) {
        logger.warn("客户端 -> exeBatRestart - 开始:{}", path);
        String exe = exeCommand("cmd", "/c", "cd", "/d", path, "&&", "start", bat);
        logger.warn("客户端 -> exeBatRestart - 结束:{}", exe);
        return exe;
    }

    public String exeServiceStart(String cmd) {
        logger.warn("客户端 -> exeServiceStart - 开始:{}", cmd);
        String exe = exeCommand("cmd", "/c", "net", "start", cmd);
        logger.warn("客户端 -> exeServiceStart - 结束:{}", exe);
        return exe;
    }

    public String exeServiceStop(String cmd) {
        logger.warn("客户端 -> exeServiceStop - 开始:{}", cmd);
        String exe = exeCommand("cmd", "/c", "net", "stop", cmd);
        logger.warn("客户端 -> exeServiceStop - 结束:{}", exe);
        return exe;
    }

    public String exeBatQuery(String name) {
        return exeQuery("cmd", "/c", "tasklist", "|", "findstr", name);
    }

    public String exeServiceQuery(String cmd) {
        return exeQuery("cmd", "/c", "sc", "query", cmd);
    }

    public String exeCommand(String... cmd) {
        logger.warn("客户端 -> 执行操作命令:{}", String.join(" ", cmd));
        try {
            // 创建一个ProcessBuilder实例，指定命令和参数
            ProcessBuilder builder = new ProcessBuilder(cmd);
            // 启动进程
            Process process = builder.start();
            // 读取输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while (reader.readLine() != null) {
            }
            // 等待进程结束并检查退出值
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                return "成功!";
            } else {
                return "错误!";
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.warn("执行命令失败\n{}", e);
        }
        return "失败";
    }


    public String exeQuery(String... cmd) {
        logger.warn("客户端 -> 执行查询命令:{}", String.join(" ", cmd));
        try {
            // 创建一个ProcessBuilder实例，指定命令和参数
            ProcessBuilder builder = new ProcessBuilder(cmd);
            // 将错误输出和标准输出合并，便于读取
            builder.redirectErrorStream(true);
            // 启动进程
            Process process = builder.start();
            // 设置字符编码为GBK
            builder.environment().put("CMD_ENCODING", "GBK");
            // 获取命令结果的输入流并读取输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
            String tasklistLine = "";
            String line;
            while ((line = reader.readLine()) != null) {
                if (Arrays.stream(cmd).filter(c -> c.equals("query")).count() > 0) {
                    //服务查询结果
                    if (line.indexOf("STATE") >= 0) {
                        String state = line.replaceAll(" ", "").split(":")[1].substring(1);
                        return STATES.get(state);
                    }
                    if (line.indexOf("FAILED") >= 0) {
                        return "查询失败";
                    }
                } else if (Arrays.stream(cmd).filter(c -> c.equals("tasklist")).count() > 0) {
                    //执行程序查询结果
                    tasklistLine += line;
                } else if (Arrays.stream(cmd).filter(c -> c.equals("netstat")).count() > 0) {
                    //查询端口结果
                    if (line.indexOf("0.0.0.0:0") >= 0) {
                        return line.replaceAll(" ", "").split("LISTENING")[1];
                    }
                } else {
                    continue;
                }
            }
            if (Arrays.stream(cmd).filter(c -> c.equals("tasklist")).count() > 0) {
                if (tasklistLine.indexOf(cmd[cmd.length - 1]) >= 0) {
                    return "运行中";
                }
                return "停止中";
            }
            // 等待进程结束并检查退出值
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                return "Success!";
            } else {
                return "Something went wrong!";
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.warn("执行命令失败\n{}", e);
        }
        return "失败";
    }

    public ArrayDeque<String> exeBuild(String cmds) {
        logger.warn("客户端 -> 执行构建:\n{}", cmds);
        String[] cmdInit = new String[]{"cmd", "/c",};
        ArrayDeque<String> list = new ArrayDeque<>();
        list.add("开始构建");
        if (StringUtils.isNotBlank(cmds)) {
            String[] arrCmds = cmds.split("\\n");
            for (int i = 0; i < arrCmds.length; i++) {
                Util.sleep(100);
                list.add("执行" + (i + 1) + "：" + arrCmds[i]);
                String[] cmd = ArrayUtils.addAll(cmdInit, arrCmds[i].split(" "));
                list.add(exeCommand(cmd));
            }
        }
        list.add("构建完成");
        return list;
    }
}
